package com.flycms.modules.data.service.impl;


import com.flycms.modules.data.domain.Weight;
import com.flycms.modules.data.service.IWeightService;
import com.flycms.modules.group.domain.GroupTopicComment;
import com.flycms.modules.group.domain.dto.GroupTopicCommentDTO;
import com.flycms.modules.group.domain.dto.GroupTopicDTO;
import com.flycms.modules.group.service.IGroupTopicCommentService;
import com.flycms.modules.group.service.IGroupTopicService;
import com.flycms.modules.statistics.domain.StatisticsAccessPage;
import com.flycms.modules.statistics.service.IStatisticsAccessPageService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Open source house, All rights reserved
 * 版权：28844.com<br/>
 * 开发公司：28844.com<br/>
 *
 * 权重统一处理服务
 *
 * @author sun-kaifei
 * @version 1.0 <br/>
 * @email 79678111@qq.com
 * @Date: 16:23 2018/10/26
 */
@Service
public class WeightServiceImpl  implements IWeightService {
    @Autowired
    private IGroupTopicService groupTopicService;

    @Autowired
    private IStatisticsAccessPageService statisticsAccessPageService;

    @Autowired
    private IGroupTopicCommentService groupTopicCommentService;

    /**
     * 更新话题权重
     *
     */
    public void updateTopicWeight(){
        int j=statisticsAccessPageService.queryStatisticsAccessPageCount(2);
        int c = j%1000==0?j/1000:j/1000+1;
        for (int i=0; i<c;i++) {
            List<StatisticsAccessPage> list = statisticsAccessPageService.getAccessPageList(2,i*1000,1000);
            for (StatisticsAccessPage info:list) {
                if(!StringUtils.isBlank(info.getUrl())){
                    Pattern p = Pattern.compile("/topic/+(\\d+)",
                            Pattern.CASE_INSENSITIVE);
                    Matcher matcher = p.matcher(info.getUrl());
                    if (matcher.find()) {
                        GroupTopicDTO topic=groupTopicService.findGroupTopicById(Long.valueOf(matcher.group(1)));
                        if(topic!=null){
                            Weight weight=new Weight();
                            GroupTopicComment topicComment=new GroupTopicComment();
                            topicComment.setTopicId(topic.getId());
                            List<GroupTopicCommentDTO> comments = groupTopicCommentService.exportGroupTopicCommentList(topicComment);
                            Optional<Integer> Ascore = Optional.of(0);
                            if (comments.size() > 0) {
                                Ascore = comments.stream()
                                        .map(comment -> comment.getCountDigg() - comment.getCountBurys())
                                        .reduce(Integer::sum);
                            }
                            weight.setAscores(Ascore.get());
                            weight.setQview(topic.getCountView());
                            weight.setQscore((topic.getCountDigg() == null ? 0 :topic.getCountDigg()) - (topic.getCountBurys() == null ? 0 :topic.getCountBurys()));
                            weight.setQanswer(topic.getCountComment());
                            //最新更新时间
                            weight.setQage((new Date().getTime()-topic.getCreateTime().getTime())/ (1000 * 60 * 60 * 24));
                            long Qupdated = 0;
                            //查询最新更新评论时间
                            GroupTopicComment comment = groupTopicCommentService.findNewestGroupTopicComment(topic.getId());
                            if(comment!=null){
                                Qupdated = (new Date().getTime()-comment.getCreateTime().getTime())/ (1000 * 60 * 60 * 24);
                            }
                            weight.setQupdated(Qupdated);
                            //更新权重
                            groupTopicService.updateWeight(this.weight(weight),topic.getId());
                        }

                    }
                }
            }
        }
    }

    /**
     * 计算话题的weight
     *
     * Stack Overflow热点问题的排名，与参与度(Qviews和Qanswers)和质量(Qscore和Ascores)成正比，与时间(Qage和Qupdated)成反比。
     *
     * Qage和Qupdated的单位都是秒。如果一个问题的存在时间越久，或者距离上一次回答的时间越久，Qage和Qupdated的值就相应增大。也就是说，随着时间流逝，这两个值都会越变越大，导致分母增大，因此总得分会越来越小。
     *
     * @param weight
     */
    public double weight(Weight weight) {
        //Math.pow(((Qage / 2) + (Qupdated/2)+1), 1.5),Qage和Qupdated的单位都是天。如果一个问题的存在时间越久，或者距离上一次回答的时间越久，Qage和Qupdated的值就相应增大。
        double weightScore = ((weight.getQview() * 4) + (weight.getQanswer() * weight.getQscore()) / 5 + weight.getAscores()) / Math.pow(((weight.getQage() / 2) + (weight.getQupdated()/2)+1), 1.5);
        return weightScore;
    }
}
